package com.macro.mall.commission.service.impl.manager;

import com.macro.mall.commission.service.AssignUserGroupResolver;
import com.macro.mall.commission.service.bo.AssignUserGroup;
import com.macro.mall.ums.entity.MemberEntity;
import com.macro.mall.ums.enums.UserLevelEnum;
import com.macro.mall.ums.service.account.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 默认分佣用户组解析器
 *
 * @author xuyanjun
 * @date 2019-09-02
 */
@Service
public class DefaultAssignUserGroupResolver implements AssignUserGroupResolver {

    @Autowired
    private MemberService userService;

    /**
     * 解析
     *
     * @param userId 用户id
     * @return 分佣用户组
     */
    @Override
    public AssignUserGroup resolve(long userId) {
        AssignUserGroup assignUserGroup = new AssignUserGroup();

        List<MemberEntity> userChain = obtainUserChain(userId);

        // 设置小二1
        setWaiter1(assignUserGroup, userChain);

        // 设置小二2
        setWaiter2(assignUserGroup, userChain);

        // 设置掌柜1
        setShopKeeper1(assignUserGroup, userChain);

        // 设置掌柜2
        setShopKeeper2(assignUserGroup, userChain);

        // 设置店长1
        setShopOwner1(assignUserGroup, userChain);

        // 设置店长2
        setShopOwner2(assignUserGroup, userChain);

        // 设置淘客
        setTk(assignUserGroup, userChain);

        return assignUserGroup;
    }

    /**
     * 获取用户链路
     *
     * @param userId 用户id
     * @return 用户链路
     */
    private List<MemberEntity> obtainUserChain(long userId) {
        List<MemberEntity> result = new ArrayList<>();
        List<Long> userIdChain = new ArrayList<>();

        MemberEntity user = userService.getById(userId);
        result.add(user);
        userIdChain.add(userId);

        if (user.getBefId() == null || user.getBefId() <= 0L) {
            return result;
        }

        if (Boolean.TRUE.equals(user.getTk())) {
            return result;
        }

        MemberEntity lastAppUser = userService.getById(user.getBefId());

        while (lastAppUser != null) {
            // 判断是否已存在，防止死循环
            if (userIdChain.contains(lastAppUser.getId())) {
                break;
            } else {
                result.add(lastAppUser);
                userIdChain.add(lastAppUser.getId());
            }

            if (Boolean.TRUE.equals(user.getTk())) {
                break;
            }

            // 无上级 则中断
            if (lastAppUser.getBefId() == null || lastAppUser.getBefId() <= 0) {
                break;
            }

            // 上级为空 则中断
            lastAppUser = userService.getById(lastAppUser.getBefId());
            if (lastAppUser == null) {
                break;
            }
        }

        return result;
    }

    /**
     * 设置小二1
     */
    private void setWaiter1(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        MemberEntity waiter1 = getFirstOfLevel(userChain, UserLevelEnum.WAITER);
        if (waiter1 != null) {
            assignUserGroup.setWaiter1(waiter1);
        }
    }

    /**
     * 设置小二2
     */
    private void setWaiter2(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        if (assignUserGroup.getWaiter1() == null) {
            return;
        }

        MemberEntity waiter2 = getFirstOfLevelAfterUser(userChain, UserLevelEnum.WAITER, assignUserGroup.getWaiter1());
        if (waiter2 != null) {
            assignUserGroup.setWaiter2(waiter2);
        }
    }

    /**
     * 设置掌柜1
     */
    private void setShopKeeper1(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        MemberEntity shopKeeper1 = getFirstOfLevel(userChain, UserLevelEnum.SHOP_KEEPER);
        if (shopKeeper1 != null) {
            assignUserGroup.setShopKeeper1(shopKeeper1);
        }
    }

    /**
     * 设置掌柜2
     */
    private void setShopKeeper2(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        if (assignUserGroup.getShopKeeper1() == null) {
            return;
        }

        MemberEntity shopKeeper2 = getFirstOfLevelAfterUser(userChain, UserLevelEnum.SHOP_KEEPER, assignUserGroup.getShopKeeper1());
        if (shopKeeper2 != null) {
            assignUserGroup.setShopKeeper2(shopKeeper2);
        }
    }

    /**
     * 设置店长1
     */
    private void setShopOwner1(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        MemberEntity shopOwner1 = getFirstOfLevel(userChain, UserLevelEnum.SHOP_OWNER);
        if (shopOwner1 != null) {
            assignUserGroup.setShopOwner1(shopOwner1);
        }
    }

    /**
     * 设置店长2
     */
    private void setShopOwner2(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        if (assignUserGroup.getShopOwner1() == null) {
            return;
        }

        MemberEntity shopOwner2 = getFirstOfLevelAfterUser(userChain, UserLevelEnum.SHOP_OWNER, assignUserGroup.getShopOwner1());
        if (shopOwner2 != null) {
            assignUserGroup.setShopOwner2(shopOwner2);
        }
    }

    /**
     * 设置淘客
     */
    private void setTk(AssignUserGroup assignUserGroup, List<MemberEntity> userChain) {
        for (MemberEntity user : userChain) {
            if (Boolean.TRUE.equals(user.getTk())) {
                assignUserGroup.setTk(user);
                return;
            }
        }
    }

    /**
     * 获取链路中第一个达到指定级别的人
     *
     * @param userChain 用户链路
     * @param userLevel 等级
     * @return 链路中第一个达到指定级别的人
     */
    private MemberEntity getFirstOfLevel(List<MemberEntity> userChain, UserLevelEnum userLevel) {
        for (MemberEntity user : userChain) {
            if (user.getLevel() >= userLevel.getValue()) {
                return user;
            }
        }
        return null;
    }

    /**
     * 获取链路中指定用户之后的第一个达到指定级别的人
     *
     * @param userChain 用户链路
     * @param userLevel 等级
     * @param afterUser 指定用户
     * @return 链路中第一个达到指定级别的人
     */
    private MemberEntity getFirstOfLevelAfterUser(List<MemberEntity> userChain, UserLevelEnum userLevel, MemberEntity afterUser) {
        int indexOfStartUserId = userChain.indexOf(afterUser);
        for (int i = indexOfStartUserId + 1; i < userChain.size(); i++) {
            MemberEntity user = userChain.get(i);
            if (user.getLevel() >= userLevel.getValue()) {
                return user;
            }
        }
        return null;
    }

    /**
     * 解析出用户链路
     *
     * @param userId 用户id
     * @return 用户链路
     */
    @Override
    public List<MemberEntity> resolveUserChain(long userId) {
        return obtainUserChain(userId);
    }

}
